package online.chazi.bootplus.commons.utils;

import io.jsonwebtoken.*;
import lombok.Data;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * 说明：作者很懒，什么都没留下
 * Created by 叉子同学 on 2020-03-24 16:54
 */
public class JwtUtils {

    @Data
    public static class Token {
        private String id;
        private String subject;
        private String issuer;
        private String audience;
        private long lifeMillisTime = 0;

        public static Token build() {
            return new Token();
        }

        public Token withId(String id) {
            this.id = id;
            return this;
        }

        public Token withSubject(String subject) {
            this.subject = subject;
            return this;
        }

        public Token withIssuer(String issuer) {
            this.issuer = issuer;
            return this;
        }

        public Token withAudience(String audience) {
            this.audience = audience;
            return this;
        }

        public Token withLifeMillisTime(long lifeMillisTime) {
            this.lifeMillisTime = lifeMillisTime;
            return this;
        }
    }

    private static SecretKey getSecretKey(String key) {
        byte[] keyBytes = Base64.decodeBase64(key);
        return new SecretKeySpec(keyBytes, 0, keyBytes.length, "AES");
    }

    public static String getJwt(Token token, String key) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        SecretKey secretKey = getSecretKey(key);
        Date now = new Date();
        JwtBuilder builder = Jwts.builder()
                .setId(token.getId())
                .setSubject(token.getSubject())   // 主题
                .setIssuer(token.getIssuer())     // 签发者
                .setAudience(token.getAudience()) // 观众
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (token.getLifeMillisTime() > 0) {
            long expMillis = now.getTime() + token.getLifeMillisTime();
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }

    public static Claims parseJwt(String jwt, String key) throws ExpiredJwtException, SignatureException, MalformedJwtException {
        SecretKey secretKey = getSecretKey(key);
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

}
